using System;
using System.Collections.Generic;
using System.Text;

namespace DatabaseCode
{
  class Utility
  {
    //str を長さ length になるように右側を c で埋める
    public static string InsertCharsToRight(string str, char c, int length)
    {
      int numInsert = length - str.Length;
      for (int i = 0; i < numInsert; i++)
      {
        str += c;
      }
      return str;
    }
    public static string InsertSpacesToRight(string str, int length)
    {
      return InsertCharsToRight(str, ' ', length);
    }

    //一行取り出す
    public static string GetLine(string str)
    {
      return GetLine(str, 0);
    }
    public static string GetLine(string str, int start_pos)
    {
      StringBuilder sb = new StringBuilder();
      for (int i = start_pos; i < str.Length; i++)
      {
        if (str[i] == '\r')
        {
          break;
        }
        sb.Append(str[i]);
      }
      return sb.ToString();
    }

    //文字列位置引数を、untilChar を飛ばした位置にする。
    //戻り値：文字列の終端に達した場合は true。
    public static bool Skip(string str, ref int pos, char untilChar)
    {
      return Skip(str, ref pos, 1, untilChar);
    }
    public static bool Skip(string str, ref int pos, int time, char untilChar)
    {
      for (int i = 0; i < time; i++)
      {
        for (; pos < str.Length; pos++)
        {
          if (str[pos] == untilChar)
          {
            pos++;
            break;
          }
        }
        if (pos >= str.Length)
          return true;
      }
      return false;
    }
    //文字列位置引数を、改行文字を飛ばした位置にする。
    //戻り値：文字列の終端に達した場合は true。
    public static bool SkipLine(string str, ref int pos)
    {
      return SkipLine(str, ref pos, 1);
    }
    public static bool SkipLine(string str, ref int pos, int time)
    {
      return Skip(str, ref pos, time, '\n');
    }

    // TableName を table_names_ にする、みたいな
    public static string MemberStringWithS_(string str)
    {
      if (str == "") return "";
      if (str == "-") return "";

      string ret = SeparateByUndercores(str);
      // 複数形にする。最後sで終わるなら、複数形esを付加する。
      return ret + (str[str.Length - 1] == 's' ? "es_" : "s_");
    }

    // TableName を table_name にする、みたいな
    public static string SeparateByUndercores(string str)
    {
      string ret = "";
      bool is_first = true;
      foreach (char c in str)
      {
        if (char.IsUpper(c))
        {
          if (is_first)
          {
            is_first = false;
            ret += char.ToLower(c);
          }
          else
          {
            ret += "_" + char.ToLower(c);
          }
        }
        else
        {
          ret += c;
        }
      }
      return ret;
    }
    // ManagerName を MANAGER_NAME にする、みたいな
    public static string UpperSeparateByUndercores(string str)
    {
      string ret = "";
      bool is_first = true;
      foreach (char c in str)
      {
        if (char.IsUpper(c))
        {
          if (is_first)
          {
            is_first = false;
            ret += c;
          }
          else
          {
            ret += "_" + c;
          }
        }
        else
        {
          ret += char.ToUpper(c);
        }
      }
      return ret;
    }

    public static bool IsLetterOrDigit(char c)
    {
      return char.IsLetterOrDigit(c);
    }
    public static bool IsLetterOrDigitOrUnderscore(char c)
    {
      return char.IsLetterOrDigit(c) || c == '_';
    }

    public static string InputSampleString()
    {
      return @"//@MgrData // Mgr を除くクラス名

//品名分類
struct ItemKind {
  int code;            // ★ 品名分類コード
  char name[kTextSize];// 品名分類名

  bool IsEqualKey(const ItemKind& r) {  return r.code == code; }
};

//品名
struct Item {
  int code;            // ★ 品名コード
  char name[kTextSize];// 品名
  int item_kind_code;  // 品名分類コード ●ItemKind.code

  bool IsEqualKey(const Item& r) {  return r.code == code; }
};

//作業者
struct Worker {
  int code;             // ★ 作業者コード
  char name[kTextSize]; // 作業者名

  bool IsEqualKey(const Worker& r) {  return r.code == code; }
};

//不良分類
struct BadKind {
  int code;            // ★ 不良分類コード
  char name[kTextSize];// 分類名

  bool IsEqualKey(const BadKind& r) {  return r.code == code; }
};

//不良項目
struct Bad {
  int code;            // ★ 不良項目コード
  char name[kTextSize];// 項目名
  int kind;            // 不良分類コード ●BadKind.code

  bool IsEqualKey(const Bad& r) {  return r.code == code; }
};

//工程
struct Process {
  int code;             // ★ 工程コード
  char name[kTextSize]; // 工程名

  bool IsEqualKey(const Process& r) {  return r.code == code; }
};

//工程詳細
struct ProcessDetail {
  int process_code;                       // ★ 工程コード
  int item_kind_code;                     // ★ 品名分類コード ●ItemKind.code
  int max_quantity;                       // 最大数量
  int good_condition_1000;                // 良品異常条件（0.1％単位）
  int bad_codes[kBadKindNumberOnProcess]; // 不良項目コード
  int bad_condition_1000[kBadKindNumberOnProcess];//不良異常条件（0.1％単位）
  char added_information_note[kTextSize]; // 付加情報説明文（号機など）
  int to_individual;                      // 個品化倍率

  bool IsEqualKey(const ProcessDetail& r) 
    {  return (r.process_code == process_code) && (r.item_kind_code == item_kind_code); }
};

//@MonData // Mgr を除くクラス名

//払出
struct LotNo {
  int code;          // ★ ロットNoコード
  char no[kTextSize];// ロットNo
  int item_code;     // 品名コード ●Item.code

  bool IsEqualKey(const LotNo& r) { return r.code == code; }
};

//プール
struct Pool {
  int process_code;      // ★ 工程コード  ●Process.code
  int lotno_code;        // ★ ロットNoコード ●LotNo.code
  int quantity;          // 数量

  bool IsEqualKey(const Pool& r)
    { return (r.process_code == process_code) && (r.lotno_code == lotno_code); }
};

//生産
struct Production {
  int process_code;                 // ★ 工程コード
  int lot_no_code;                   // ★ ロットNoコード
  int good;                         // 良品数
  base::Time production_time;       // 作業日時
  base::Time Input_time;            // 入力日時
  char added_information[kTextSize];// 付加情報（号機など）
  int bad[kBadKindNumberOnProcess]; // 不良数
  int worker_code;                  // 作業者 ●Worker.code

  bool IsEqualKey(const Production& r) 
    { return (r.process_code == process_code) && (r.lot_no_code == lot_no_code); }
};

//工程異常
struct RedPaper {
  int code;                   // ★ 工程異常コード
  int process_code;           // 工程 ●Process.code
  int lot_no_code;             // ロットNo
  char publisher[kTextSize];  // 発行者
  base::Time when;            // いつ
  char who[kTextSize];        // なぜ
  char place[kTextSize];      // どこで
  char bad[kTextSize];        // 異常項目
  char content[kLongTextSize];// 内容

  bool IsEqualKey(const RedPaper& r) { return r.code == code; }
};";
    }
  }
}
